﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;

using System;
using System.IO;

namespace Holla.Infrastructure.EntityFramework
{
    public abstract class DesignTimeDbContextFactoryBase<TContext> : IDesignTimeDbContextFactory<TContext>
          where TContext : DbContext
    {
        protected abstract string ConnectionStringName { get; }
        protected abstract string MainProjectName { get; }
        protected abstract string MigrationAssembly { get; }


        public TContext CreateDbContext(string[] args)
        {
            var basePath = $"{Directory.GetCurrentDirectory()}{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}{MainProjectName}";
            return Create(basePath, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
        }

        private TContext Create(string basePath, string environmentName)
        {
            var configuration = new ConfigurationBuilder().SetBasePath(basePath)
               .AddJsonFile("appsettings.json")
               .AddJsonFile("appsettings.Local.json", optional: true)
               .AddJsonFile($"appsettings.{environmentName}.json", optional: true)
               .AddEnvironmentVariables()
               .Build();

            var connectionString = configuration.GetConnectionString(ConnectionStringName);

            if (string.IsNullOrEmpty(connectionString))
            {
                throw new Exception($"Connection string '{ConnectionStringName}' is null or empty.");
            }

            Console.WriteLine($"DesignTimeDbContextFactoryBase.Create(string): Connection string: '{connectionString}'.");

            var optionsBuilder = new DbContextOptionsBuilder<TContext>();
            optionsBuilder.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(MigrationAssembly));
            return CreateNewInstance(optionsBuilder.Options);
        }

        protected abstract TContext CreateNewInstance(DbContextOptions<TContext> options);
    }
}
